#include "Slave.h"

Slave::Slave(){
	
}

void Slave::SetParameters(int _slaveId, int _receiveBufferSize)
{
	this->slaveId = _slaveId;
	this->receiveBufferSize = _receiveBufferSize;
	this->receiveBuffer = new char[receiveBufferSize];
}

void Slave::Start()
{
	if (this->receiveBufferSize==0){
		printf("Call SetParameters() method first\n");
		return;
	}
	
	MPI_Request request;
	MPI_Status status;
	int receivedFrom = -1;
	
	printf("Rank%d: Receiving \n", this->slaveId);
	
	MPI_Irecv (receiveBuffer, receiveBufferSize, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
		           &request);
	MPI_Wait (&request, &status);
	
	receivedFrom = status.MPI_SOURCE;
	
	printf("Rank%d: Received from %d\n", this->slaveId, receivedFrom);
	
	switch(status.MPI_TAG)
	{
			default:
				printf("Rank%d: Unknown TAG received from %d\n", slaveId, receivedFrom);
				return;
			
			case TAG_TERMINATE:
				printf("Rank%d: Received TERMINATE TAG from %d\n", slaveId, receivedFrom);
				return;
				
			case TAG_JOB:
				printf("Rank%d: Received JOB TAG from %d\n", slaveId, receivedFrom);
				CreateThread(receivedFrom);
				return;
	}
}

void Slave::CreateThread(int receivedFrom)
{
	printf("Rank%d: Creating thread...\n", slaveId);
	
	pthread_t thread;	
	
	pthread_create( &thread, NULL, Slave::callWorkerThread, (void*)&receivedFrom);
	pthread_join( thread, NULL);
}

// Metoda uruchomiona przez hack (funkcje callWorkerThread)
void* Slave::WorkerThread(int receivedFrom)
{
	printf("Rank%d: MessageFromThread\n", slaveId);
}
